package prefuse.decisiontree;

import javax.swing.JOptionPane;

import prefuse.decisiontree.api.Edge;
import prefuse.decisiontree.api.TreeNode;


/**
 * An BasicEdge represents the path connecting two TreeNodes. It has a weight, 
 * which is the time difference between source and destination nodes. It has 
 * a probability, which is the liklihood that this path is chosen.
 * 
 * @invariant source node is not null
 * @invariant destination node is not null
 * @invariant probability is between 0-1
 * 
 * @author SaskTrav
 * @editor Wenyi An
 */
public class BasicEdge implements Edge {

    private double value;               // Value of the specified attribute from the source node
    private TreeNode sourceNode;        // Source tree node of this instance
    private TreeNode destinationNode;   // Destination tree node of this instance
    private boolean selected;
    private int edgeID;
    private double pathValue;
    private String name=null;
    private String EdgeType = "BasicEdge";
    
    /** Constructor for BasicEdge
     * 
     * @param edgeWeight Weight of new edge, must be positive value
     * @param source Source Node for new edge, cannot be null
     * @param destination Destination node for new edge, cannot be null
     * @throws java.lang.IllegalArgumentException Thrown if any of the parameters are outside expectations
     */
    public BasicEdge(TreeNode newSourceNode, TreeNode newDestination, int theEdgeID,String name) throws IllegalArgumentException
    {
        if(newSourceNode == null)
        {
        	JOptionPane.showMessageDialog(null,"Source Node of a BasicEdge cannot be null");
            throw new IllegalArgumentException("Source Node of a BasicEdge cannot be null");
        }
        if(newDestination == null)
        {
        	JOptionPane.showMessageDialog(null,"Destination Node of a BasicEdge cannot be null");
            throw new IllegalArgumentException("Destination Node of a BasicEdge cannot be null");
        }
        if(newSourceNode == newDestination)
        {
        	JOptionPane.showMessageDialog(null,"Root Node and Destination cannot be the same.");
            throw new IllegalArgumentException("Root Node and Destination cannot be the same.");
        }

        this.sourceNode = newSourceNode;
        this.destinationNode = newDestination;
        this.selected = false;
        this.value = Double.NaN;
        this.edgeID = theEdgeID;
        this.pathValue = Double.NaN;
        this.name = name;
    }

    public String getEdgeType(){
    	return this.EdgeType;
    }
    /**
     * Retrieves the Path value of the edge
     * @return
     */
    public double getPathValue()
    {
        return this.pathValue;
    }

    /**
     * assigns the current edge with a path value
     * @param pathValue
     */
    public void setPathValue(double thePathValue)
    {
        this.pathValue = thePathValue;
    }
    /**
     * Retrieves the Path value of the edge
     * @return
     */
    public String getEdgeName()
    {
        return this.name;
    }

    /**
     * assigns the current edge with a path value
     * @param pathValue
     */
    public void setEdgeName(String name)
    {
        this.name = name;
    }
    /**
     * retrieves the EdgeID
     * @return edgeID
     */
    public int getEdgeID()
    {
        return this.edgeID;
    }
     /**
     * Identifies the Edge as selected or not
     * @return  True if selected
     *          False if not selected
     */
    public boolean isSelected()
    {
        return this.selected;
    }

    /**
     * Assigns the current Edge to selected or not selected
     * @questioin might convert to two functions, select/unselect
     */
    public void setSelected(boolean newSelect)
    {
        this.selected = newSelect;
    }
    /**
     * Retrieves the value of the specified attribute from the source node
     * @retrun A double value that represents the value of the specified
     * attribute from the source node
     */
    public double getValue()
    {
        return this.value;
    }


    /**
     * Retrieves the value of the specified attribute from the source node
     *
     * @postcondition getValue will return the value provided by theValue
     */
    public void setValue(Double newValue)
    {
        this.value = newValue;
    }


        /**
     * Assign the TreeNode representing the source of this Edge.
     * throw IllegalArgumentException if theSourceNode is the destination node or null
     * @see TreeNode
     */
    public void setSourceNode(TreeNode theSourceNode) throws IllegalArgumentException
    {
        if (this.destinationNode == theSourceNode)
        {
        	JOptionPane.showMessageDialog(null,"The Source node and Destination Node cannot be the same");
            throw new IllegalArgumentException("The Source node and Destination Node cannot be the same");
        }
        else if(theSourceNode == null)
        {
        	JOptionPane.showMessageDialog(null,"The Source Node cannot be null");
            throw new IllegalArgumentException("The Source Node cannot be null");
        }
        this.sourceNode = theSourceNode;
    }

    /**
     * Assign the TreeNode representing the destination of this Edge.
     * throw IllegalArgumentException if theDestinationNode is the source node or nul
     * @precondition ens
     * @see TreeNode
     */
    public void setDestinationNode(TreeNode theDestinationNode) throws IllegalArgumentException
    {
        if(this.sourceNode ==  theDestinationNode )
        {
        	JOptionPane.showMessageDialog(null,"The Destination node and the source node cannot be the same");
            throw new IllegalArgumentException("The Destination node and the source node cannot be the same");
        }
        else if (theDestinationNode == null)
        {
        	JOptionPane.showMessageDialog(null,"The Destination node cannot be null");
            throw new IllegalArgumentException("The Destination node cannot be null");
        }
        this.destinationNode = theDestinationNode;
    }

    /**
     * Retrieve the TreeNode representing the source of this Edge.
     * 
     * @return A TreeNode at which the edge originates.
     * @see TreeNode
     */
    public TreeNode getSourceNode()
    {
        return this.sourceNode;
    }
    
    /**
     * Retrieve the TreeNode representing the destination of this Edge.
     * 
     * @return A TreeNode at which the edge terminates.
     * @see TreeNode
     */
    public TreeNode getDestinationNode()
    {
        return this.destinationNode;
    }
    
}
